using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections;

namespace Acms.WebControls
{
    [DefaultProperty("Text")]
    [ToolboxData("<{0}:CheckBoxList runat=server></{0}:CheckBoxList>")]
    public class CheckBoxList : CompositeDataBoundControl
    {
        private string dataValueField;
        public string DataValueField
        {
            get{return dataValueField;}
            set { dataValueField = value; }
        }

        private string dataTextField;
        public string DataTextField
        {
            get { return dataTextField; }
            set { dataTextField = value; }
        }

        private string textFieldFormat;
        public string TextFieldFormat
        {
            get { return textFieldFormat; }
            set { textFieldFormat = value; }
        }

        private string dataCheckedField;
        public string DataCheckedField
        {
            get { return dataCheckedField; }
            set { dataCheckedField = value; }
        }

        protected override HtmlTextWriterTag TagKey
        {
            get
            {
                return HtmlTextWriterTag.Span;
            }
        }

        protected override int CreateChildControls(System.Collections.IEnumerable dataSource, bool dataBinding)
        {
            items = new List<CheckBox>();
            System.Collections.IEnumerator bindingSource = null;
            if (dataBinding)
            {
                values = new ArrayList();
                dataItems = new ArrayList();
                if(dataSource == null)
                {
                    return 0;
                }
                bindingSource = dataSource.GetEnumerator();
            }
            else
            {
                object[] tmp = new object[totalItems];
                bindingSource = tmp.GetEnumerator();
            }
            int i = 0;
            while (bindingSource.MoveNext())
            {
                i++;
                CreateItem(i);
                if (dataBinding)
                {
                    dataItems.Add(bindingSource.Current);
                }
            }
            if(dataBinding)
            {
                for (int n = 0; n < i; n++)
                {
                    DataBindItem(n);
                }
            }
            totalItems = i;
            return totalItems;
        }

        private int totalItems;

        protected override object SaveViewState()
        {
            ViewState["totalItems"] = totalItems;
            if (values != null)
            {
                ViewState["values"] = values.ToArray();
            }
            else
            {
                ViewState.Remove("values");
            }

            return base.SaveViewState();
        }

        protected override void LoadViewState(object savedState)
        {
            base.LoadViewState(savedState);
            if (ViewState["totalItems"] is int)
                totalItems = (int)ViewState["totalItems"];
            if (ViewState["values"] is Array)
            {
                values = new ArrayList();
                foreach (object o in (Array)ViewState["values"])
                {
                    values.Add(o);
                }
            }
        }

        private List<CheckBox> items;
        public CheckBox[] Items
        {
            get
            {
                EnsureChildControls();
                return items.ToArray(); 
            }
        }
        private ArrayList dataItems;
        private ArrayList values;
        public object[] Values
        {
            get
            {
                return values.ToArray();
            }
        }
        
        public object GetValue(CheckBox item)
        {
            EnsureChildControls();
            if (item != null && items.Contains(item))
            {
                return values[items.IndexOf(item)];
            }
            else
            {
                return null;
            }
        }

        private void CreateItem(int i)
        {
            CheckBox checkBox = new CheckBox();
            checkBox.ID = string.Concat("item", i);
            this.Controls.Add(checkBox);
            items.Add(checkBox);
            OnItemCreated(new ItemCreatedEventArgs(checkBox));
        }

        private void DataBindItem(int i)
        {
            CheckBox cb = items[i];
            object di = dataItems[i];

            if (!string.IsNullOrEmpty(DataTextField))
            {
                cb.Text = DataBinder.Eval(di, DataTextField, TextFieldFormat);
            }
            if (!string.IsNullOrEmpty(DataValueField))
            {
                values.Add(DataBinder.Eval(di, DataValueField));
            }
            else
            {
                values.Add(null);
            }
            if (!string.IsNullOrEmpty(DataCheckedField))
            {
                object tmp = DataBinder.Eval(di, DataCheckedField);
                if (tmp is bool)
                {
                    cb.Checked = (bool)tmp;
                }
            }

            ItemDataBoundEventArgs e = new ItemDataBoundEventArgs(items[i], dataItems[i], values[i]);
            OnItemDataBound(e);
            values[i] = e.Value;
        }

        protected void OnItemCreated(ItemCreatedEventArgs e)
        {
            if (this.ItemCreated != null)
            {
                ItemCreated(this, e);
            }
        }

        protected void OnItemDataBound(ItemDataBoundEventArgs e)
        {
            if (this.ItemDataBound != null)
            {
                ItemDataBound(this, e);
            }
        }
        
        public event EventHandler<ItemCreatedEventArgs> ItemCreated;
        public event EventHandler<ItemDataBoundEventArgs> ItemDataBound;

        public class ItemCreatedEventArgs : EventArgs
        {
            public ItemCreatedEventArgs(CheckBox item)
            {
                this.item = item;
            }

            private CheckBox item;
            public CheckBox Item
            {
                get{return item;}
            }
        }

        public class ItemDataBoundEventArgs : ItemCreatedEventArgs
        {
            public ItemDataBoundEventArgs(CheckBox item, object dataItem, object value)
                : base(item)
            {
                this.dataItem = dataItem;
                this.value = value;
            }

            private object dataItem;
            public object DataItem
            {
                get { return dataItem; }
            }

            private object value;
            public object Value
            {
                get { return value; }
            }
        }
    }

}
